<?php


namespace Tbf\Component\Http\ServeFile;


use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\StreamedResponse;

class ServeFile {
    static protected $init=false;
    /**
     * 由php提供文件服务,
     * 1.使用symfony的response缓存 半小时
     * 2.基于修改的时间的304缓存
     * func(request Request,file_map FileMapInterface)(Response,error)
     * @param Request $request
     * @param string $file_map
     * @return Response
     */
    static function serviceSymfony(Request $request,$file_path){
        if (!self::$init){
            MimeTypeGuesser::getInstance()->register(new ExtensionMimeTypeGuesser());
            self::$init = true;
        }
        try{
            $mini_type = MimeTypeGuesser::getInstance()->guess($file_path);
        }catch(\LogicException $e){ //缺少guesser
            $mini_type = null;
        }catch(\Exception $e){ //文件打不开
            return array(null,$e->getMessage());
        }

        $last_modified = filemtime($file_path);
        $response = new StreamedResponse();
        $response->setLastModified(\DateTime::createFromFormat('U',$last_modified));
        $date = new \DateTime();
        $date->modify('+1800 seconds');
        $response->setExpires($date);
        $response->setSharedMaxAge(1800);
        $response->setMaxAge(1800);

        if ($response->isNotModified($request)){ //直接返回304
            $response->setCallback(function(){});
            return array($response,null);
        }
        $response->setCallback(function()use($file_path){
            $res = fopen($file_path,'r');
            while(!feof($res)){
                echo fread($res,256*1024);
            }
            fclose($res);
        });

        if (!empty($mini_type)){
            $response->headers->set('Content-Type',$mini_type);
        }else{
            $response->headers->set('Content-Type','application/octet-stream');
        }
        $response->setCache(array());
        return array($response,null);
    }
}